package mvc.imageProcessor.impl;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;

import mvc.core.impl.MachuImage;
import mvc.effects.IEffect;
import mvc.imageProcessor.IImageProcessor;

public class ImageProcessor implements IImageProcessor {

	public ImageProcessor() {
	}

	/**
	 * Processes all the effects in the MachuImage effects list and returns a
	 * BufferdImage of given width and height.
	 * 
	 */
	@Override
	public BufferedImage processImage(MachuImage img, int width, int height)
			throws IOException {

		BufferedImage temp = (BufferedImage) createScaledImage(
				getFullSizeImage(img), width, height);
		List<IEffect> effectsList = img.getEffectsList();

		for (IEffect fx : effectsList) {
			temp = fx.applyEffect(temp);
		}
		return temp;
	}

	/**
	 * Processes all the thumbnail images of a list by applying the last added
	 * effect to each image.
	 * 
	 * @param selectedImages
	 */
	public void processThumbnailImages(List<MachuImage> selectedImages) {
		for (MachuImage tmp : selectedImages) {
			BufferedImage thumb = (BufferedImage) tmp.getThumbnail();
			IEffect lastFx = tmp.getEffectsList().get(tmp.getEffectsList().size()-1);
			thumb = lastFx.applyEffect(thumb);
			tmp.setThumbnail(thumb);
		}
	}

	/**
	 * Scales an Image to preferred size. If width is of negative value scales
	 * the Image with a 1:1 ratio according to the height. And vice versa.
	 */
	public Image createScaledImage(Image img, int width, int height)
			throws IOException {

		if (width < 0 && height < 0) {
			width = img.getWidth(null);
			height = img.getHeight(null);
		} else if (width < 0) {
			width = img.getWidth(null) * height / img.getHeight(null);
		} else if (height < 0) {
			height = img.getHeight(null) * width / img.getWidth(null);
		}

		BufferedImage dest = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = dest.createGraphics();
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BICUBIC);
		g2.drawImage(img, 0, 0, width, height, null);
		g2.dispose();

		return dest;
	}

	/**
	 * Returns a fullsize BufferedImage object from a MachuImage object. 
	 */
	@Override
	public Image getFullSizeImage(MachuImage img) throws IOException {
		BufferedImage temp = ImageIO.read(img.getFile());
		return temp;
	}
}
